﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace APP.HELPER.Utils.Excel
{
    #region Internal Enum
    internal enum BIFFRECORDTYPE : ushort
    {
        INTERFACEHDR = 225,
        MMS = 193,
        INTERFACEEND = 226,
        WRITEACCESS = 92,
        CODEPAGE = 66,
        DSF = 353,
        TABID = 317,
        FNGROUPCOUNT = 156,
        WINDOWPROTECT = 25,
        PROTECT = 18,
        PASSWORD,
        PROT4REV = 431,
        PROT4REVPASSWORD = 444,
        WINDOW1 = 61,
        BACKUP = 64,
        HIDEOBJ = 141,
        RECORD1904 = 34,
        REFRESHALL = 439,
        BOOKBOOL = 218,
        FONT = 49,
        FONT_V34 = 561,
        FORMAT = 1054,
        FORMAT_V23 = 30,
        XF = 224,
        XF_V4 = 1091,
        XF_V3 = 579,
        XF_V2 = 67,
        STYLE = 659,
        BOUNDSHEET = 133,
        COUNTRY = 140,
        SST = 252,
        CONTINUE = 60,
        EXTSST = 255,
        BOF = 2057,
        BOF_V2 = 9,
        BOF_V3 = 521,
        BOF_V4 = 1033,
        EOF = 10,
        CALCCOUNT = 12,
        CALCMODE,
        PRECISION,
        REFMODE,
        DELTA,
        ITERATION,
        SAVERECALC = 95,
        PRINTHEADERS = 42,
        PRINTGRIDLINES,
        GUTS = 128,
        WSBOOL,
        GRIDSET,
        DEFAULTROWHEIGHT = 549,
        HEADER = 20,
        FOOTER,
        HCENTER = 131,
        VCENTER,
        PRINTSETUP = 161,
        DFAULTCOLWIDTH = 85,
        DIMENSIONS = 512,
        ROW = 520,
        WINDOW2 = 574,
        SELECTION = 29,
        INDEX = 523,
        DBCELL = 215,
        BLANK = 513,
        BLANK_OLD = 1,
        MULBLANK = 190,
        INTEGER = 514,
        INTEGER_OLD = 2,
        NUMBER = 515,
        NUMBER_OLD = 3,
        LABEL = 516,
        LABEL_OLD = 4,
        LABELSST = 253,
        FORMULA = 1030,
        FORMULA_OLD = 6,
        BOOLERR = 517,
        BOOLERR_OLD = 5,
        ARRAY = 545,
        RK = 638,
        MULRK = 189,
        RSTRING = 214,
        SHRFMLA = 1212,
        SHRFMLA_OLD = 188,
        STRING = 519,
        CF = 433,
        CODENAME = 442,
        CONDFMT = 432,
        DCONBIN = 437,
        DV = 446,
        DVAL = 434,
        HLINK = 440,
        MSODRAWINGGROUP = 235,
        MSODRAWING,
        MSODRAWINGSELECTION,
        PARAMQRY = 220,
        QSI = 429,
        SUPBOOK,
        SXDB = 198,
        SXDBEX = 290,
        SXFDBTYPE = 443,
        SXRULE = 240,
        SXEX,
        SXFILT,
        SXNAME = 246,
        SXSELECT,
        SXPAIR,
        SXFMLA,
        SXFORMAT = 251,
        SXFORMULA = 259,
        SXVDEX = 256,
        TXO = 438,
        USERBVIEW = 425,
        USERSVIEWBEGIN,
        USERSVIEWEND,
        USESELFS = 352,
        XL5MODIFY = 354,
        OBJ = 93,
        NOTE = 28,
        SXEXT = 220,
        VERTICALPAGEBREAKS = 26,
        XCT = 89
    }
    internal enum BIFFTYPE : ushort
    {
        WorkbookGlobals = 5,
        VBModule,
        Worksheet = 16,
        Chart = 32,
        v4MacroSheet = 64,
        v4WorkbookGlobals = 256
    }
    internal enum DECOLOR : byte
    {
        DE_RED,
        DE_BLACK
    }
    internal enum FATMARKERS : uint
    {
        FAT_EndOfChain = 4294967294u,
        FAT_FreeSpace,
        FAT_FatSector = 4294967293u,
        FAT_DifSector = 4294967292u
    }
    internal enum FORMULAERROR : byte
    {
        NULL,
        DIV0 = 7,
        VALUE = 15,
        REF = 23,
        NAME = 29,
        NUM = 36,
        NA = 42
    }
    internal enum STGTY : byte
    {
        STGTY_INVALID,
        STGTY_STORAGE,
        STGTY_STREAM,
        STGTY_LOCKBYTES,
        STGTY_PROPERTY,
        STGTY_ROOT
    }
    #endregion

    #region Exception class
    public class InvalidHeaderException : Exception
    {
        public InvalidHeaderException()
        {
        }
        public InvalidHeaderException(string message)
            : base(message)
        {
        }
        public InvalidHeaderException(string message, Exception innerException)
            : base(message, innerException)
        {
        }
    }
    #endregion

    #region Excel Defined Help Class
    internal class XlsBiffBlankCell : XlsBiffRecord
    {
        public ushort RowIndex
        {
            get
            {
                return base.ReadUInt16(0);
            }
        }
        public ushort ColumnIndex
        {
            get
            {
                return base.ReadUInt16(2);
            }
        }
        public ushort XFormat
        {
            get
            {
                return base.ReadUInt16(4);
            }
        }
        internal XlsBiffBlankCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffBlankCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffBOF : XlsBiffRecord
    {
        public ushort Version
        {
            get
            {
                return base.ReadUInt16(0);
            }
        }
        public BIFFTYPE Type
        {
            get
            {
                return (BIFFTYPE)base.ReadUInt16(2);
            }
        }
        public ushort CreationID
        {
            get
            {
                ushort result;
                if (base.RecordSize < 6)
                {
                    result = 0;
                }
                else
                {
                    result = base.ReadUInt16(4);
                }
                return result;
            }
        }
        public ushort CreationYear
        {
            get
            {
                ushort result;
                if (base.RecordSize < 8)
                {
                    result = 0;
                }
                else
                {
                    result = base.ReadUInt16(6);
                }
                return result;
            }
        }
        public uint HistoryFlag
        {
            get
            {
                uint result;
                if (base.RecordSize < 12)
                {
                    result = 0u;
                }
                else
                {
                    result = base.ReadUInt32(8);
                }
                return result;
            }
        }
        public uint MinVersionToOpen
        {
            get
            {
                uint result;
                if (base.RecordSize < 16)
                {
                    result = 0u;
                }
                else
                {
                    result = base.ReadUInt32(12);
                }
                return result;
            }
        }
        internal XlsBiffBOF(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffBOF(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
    }
    internal class XlsBiffBoolErrCell : XlsBiffBlankCell
    {
        public FORMULAERROR ErrorCode
        {
            get
            {
                return (FORMULAERROR)base.ReadByte(6);
            }
        }
        public bool Value
        {
            get
            {
                return base.ReadByte(6) != 0;
            }
        }
        public bool IsError
        {
            get
            {
                return base.ReadByte(7) != 0;
            }
        }
        internal XlsBiffBoolErrCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffBoolErrCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
    }
    internal class XlsBiffBoundSheet : XlsBiffRecord
    {
        public enum SheetType : byte
        {
            Worksheet,
            MacroSheet,
            Chart,
            VBModule = 6
        }
        public enum SheetVisibility : byte
        {
            Visible,
            Hidden,
            VeryHidden
        }
        private Encoding m_UseEncoding = Encoding.Default;
        private bool isV8 = true;
        public uint StartOffset
        {
            get
            {
                return base.ReadUInt32(0);
            }
        }
        public XlsBiffBoundSheet.SheetType Type
        {
            get
            {
                return (XlsBiffBoundSheet.SheetType)base.ReadByte(4);
            }
        }
        public XlsBiffBoundSheet.SheetVisibility VisibleState
        {
            get
            {
                return (XlsBiffBoundSheet.SheetVisibility)(base.ReadByte(5) & 3);
            }
        }
        public string SheetName
        {
            get
            {
                ushort num = (ushort)base.ReadByte(6);
                ushort recordSize = base.RecordSize;
                int num2 = 8;
                string @string;
                if (this.isV8)
                {
                    if (base.ReadByte(7) == 0)
                    {
                        @string = Encoding.Default.GetString(this.m_bytes, this.m_readoffset + num2, (int)num);
                    }
                    else
                    {
                        @string = this.m_UseEncoding.GetString(this.m_bytes, this.m_readoffset + num2, (int)(this.m_UseEncoding.IsSingleByte ? num : (num * 2)));
                    }
                }
                else
                {
                    @string = Encoding.Default.GetString(this.m_bytes, this.m_readoffset + num2 - 1, (int)num);
                }
                return @string;
            }
        }
        public Encoding UseEncoding
        {
            get
            {
                return this.m_UseEncoding;
            }
            set
            {
                this.m_UseEncoding = value;
            }
        }
        public bool IsV8
        {
            get
            {
                return this.isV8;
            }
            set
            {
                this.isV8 = value;
            }
        }
        internal XlsBiffBoundSheet(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffBoundSheet(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffContinue : XlsBiffRecord
    {
        internal XlsBiffContinue(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffContinue(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffDbCell : XlsBiffRecord
    {
        public int RowAddress
        {
            get
            {
                return base.Offset - base.ReadInt32(0);
            }
        }
        public uint[] CellAddresses
        {
            get
            {
                int num = this.RowAddress - 20;
                List<uint> list = new List<uint>();
                for (int i = 4; i < (int)base.RecordSize; i += 4)
                {
                    list.Add((uint)(num + (int)base.ReadUInt16(i)));
                }
                return list.ToArray();
            }
        }
        internal XlsBiffDbCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffDbCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffDimensions : XlsBiffRecord
    {
        private bool isV8 = true;
        public bool IsV8
        {
            get
            {
                return this.isV8;
            }
            set
            {
                this.isV8 = value;
            }
        }
        public uint FirstRow
        {
            get
            {
                return this.isV8 ? base.ReadUInt32(0) : ((uint)base.ReadUInt16(0));
            }
        }
        public uint LastRow
        {
            get
            {
                return this.isV8 ? base.ReadUInt32(4) : ((uint)base.ReadUInt16(2));
            }
        }
        public ushort FirstColumn
        {
            get
            {
                return this.isV8 ? base.ReadUInt16(8) : base.ReadUInt16(4);
            }
        }
        public ushort LastColumn
        {
            get
            {
                return this.isV8 ? base.ReadUInt16(16) : base.ReadUInt16(6);
            }
        }
        internal XlsBiffDimensions(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffDimensions(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffEOF : XlsBiffRecord
    {
        internal XlsBiffEOF(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffEOF(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffFormulaCell : XlsBiffNumberCell
    {
        [Flags]
        public enum FormulaFlags : ushort
        {
            AlwaysCalc = 1,
            CalcOnLoad = 2,
            SharedFormulaGroup = 8
        }
        private Encoding m_UseEncoding = Encoding.Default;
        public Encoding UseEncoding
        {
            get
            {
                return this.m_UseEncoding;
            }
            set
            {
                this.m_UseEncoding = value;
            }
        }
        public XlsBiffFormulaCell.FormulaFlags Flags
        {
            get
            {
                return (XlsBiffFormulaCell.FormulaFlags)base.ReadUInt16(14);
            }
        }
        public byte FormulaLength
        {
            get
            {
                return base.ReadByte(15);
            }
        }
        public new object Value
        {
            get
            {
                long num = base.ReadInt64(6);
                object result;
                if ((num & -281474976710656L) == -281474976710656L)
                {
                    byte b = (byte)(num & 255L);
                    byte b2 = (byte)(num >> 16 & 255L);
                    switch (b)
                    {
                        case 0:
                            {
                                XlsBiffFormulaString xlsBiffFormulaString = XlsBiffRecord.GetRecord(this.m_bytes, (uint)(base.Offset + base.Size)) as XlsBiffFormulaString;
                                if (xlsBiffFormulaString == null)
                                {
                                    result = string.Empty;
                                }
                                else
                                {
                                    xlsBiffFormulaString.UseEncoding = this.m_UseEncoding;
                                    result = xlsBiffFormulaString.Value;
                                }
                                break;
                            }
                        case 1:
                            result = (b2 != 0);
                            break;
                        case 2:
                            result = (FORMULAERROR)b2;
                            break;
                        default:
                            result = null;
                            break;
                    }
                }
                else
                {
                    result = BitConverter.Int64BitsToDouble(num);
                }
                return result;
            }
        }
        public string Formula
        {
            get
            {
                return Encoding.Default.GetString(base.ReadArray(16, (int)this.FormulaLength));
            }
        }
        internal XlsBiffFormulaCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffFormulaCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
    }
    internal class XlsBiffFormulaString : XlsBiffRecord
    {
        private Encoding m_UseEncoding = Encoding.Default;
        public Encoding UseEncoding
        {
            get
            {
                return this.m_UseEncoding;
            }
            set
            {
                this.m_UseEncoding = value;
            }
        }
        public ushort Length
        {
            get
            {
                return base.ReadUInt16(0);
            }
        }
        public string Value
        {
            get
            {
                return this.m_UseEncoding.GetString(this.m_bytes, this.m_readoffset + (this.m_UseEncoding.IsSingleByte ? 2 : 3), (int)(this.Length * (this.m_UseEncoding.IsSingleByte ? 1 : 2)));
            }
        }
        internal XlsBiffFormulaString(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffFormulaString(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
    }
    internal class XlsBiffIndex : XlsBiffRecord
    {
        private bool isV8 = true;
        public bool IsV8
        {
            get
            {
                return this.isV8;
            }
            set
            {
                this.isV8 = value;
            }
        }
        public uint FirstExistingRow
        {
            get
            {
                return this.isV8 ? base.ReadUInt32(4) : ((uint)base.ReadUInt16(4));
            }
        }
        public uint LastExistingRow
        {
            get
            {
                return this.isV8 ? base.ReadUInt32(8) : ((uint)base.ReadUInt16(6));
            }
        }
        public uint[] DbCellAddresses
        {
            get
            {
                int recordSize = (int)base.RecordSize;
                int num = this.isV8 ? 16 : 12;
                uint[] result;
                if (recordSize <= num)
                {
                    result = new uint[0];
                }
                else
                {
                    List<uint> list = new List<uint>((recordSize - num) / 4);
                    for (int i = num; i < recordSize; i += 4)
                    {
                        list.Add(base.ReadUInt32(i));
                    }
                    result = list.ToArray();
                }
                return result;
            }
        }
        internal XlsBiffIndex(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffIndex(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffIntegerCell : XlsBiffBlankCell
    {
        public uint Value
        {
            get
            {
                return (uint)base.ReadUInt16(6);
            }
        }
        internal XlsBiffIntegerCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffIntegerCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
    }
    internal class XlsBiffInterfaceHdr : XlsBiffRecord
    {
        public ushort CodePage
        {
            get
            {
                return base.ReadUInt16(0);
            }
        }
        internal XlsBiffInterfaceHdr(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffInterfaceHdr(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffLabelCell : XlsBiffBlankCell
    {
        private Encoding m_UseEncoding = Encoding.Default;
        public Encoding UseEncoding
        {
            get
            {
                return this.m_UseEncoding;
            }
            set
            {
                this.m_UseEncoding = value;
            }
        }
        public byte Length
        {
            get
            {
                return base.ReadByte(6);
            }
        }
        public string Value
        {
            get
            {
                return this.m_UseEncoding.GetString(base.ReadArray(8, (int)(this.Length * (this.m_UseEncoding.IsSingleByte ? 1 : 2))));
            }
        }
        internal XlsBiffLabelCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffLabelCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
    }
    internal class XlsBiffLabelSSTCell : XlsBiffBlankCell
    {
        public uint SSTIndex
        {
            get
            {
                return base.ReadUInt32(6);
            }
        }
        internal XlsBiffLabelSSTCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffLabelSSTCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        public string Text(XlsBiffSST sst)
        {
            return sst.GetString(this.SSTIndex);
        }
    }
    internal class XlsBiffMulBlankCell : XlsBiffBlankCell
    {
        public ushort LastColumnIndex
        {
            get
            {
                return base.ReadUInt16((int)(base.RecordSize - 2));
            }
        }
        internal XlsBiffMulBlankCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffMulBlankCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        public ushort GetXF(ushort ColumnIdx)
        {
            int num = (int)(4 + 6 * (ColumnIdx - base.ColumnIndex));
            ushort result;
            if (num > (int)(base.RecordSize - 2))
            {
                result = 0;
            }
            else
            {
                result = base.ReadUInt16(num);
            }
            return result;
        }
    }
    internal class XlsBiffMulRKCell : XlsBiffBlankCell
    {
        public ushort LastColumnIndex
        {
            get
            {
                return base.ReadUInt16((int)(base.RecordSize - 2));
            }
        }
        internal XlsBiffMulRKCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffMulRKCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        public ushort GetXF(ushort ColumnIdx)
        {
            int num = (int)(4 + 6 * (ColumnIdx - base.ColumnIndex));
            ushort result;
            if (num > (int)(base.RecordSize - 2))
            {
                result = 0;
            }
            else
            {
                result = base.ReadUInt16(num);
            }
            return result;
        }
        public double GetValue(ushort ColumnIdx)
        {
            int num = (int)(6 + 6 * (ColumnIdx - base.ColumnIndex));
            double result;
            if (num > (int)base.RecordSize)
            {
                result = 0.0;
            }
            else
            {
                result = XlsBiffRKCell.NumFromRK(base.ReadUInt32(num));
            }
            return result;
        }
    }
    internal class XlsBiffNumberCell : XlsBiffBlankCell
    {
        public double Value
        {
            get
            {
                return base.ReadDouble(6);
            }
        }
        internal XlsBiffNumberCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffNumberCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
    }
    internal class XlsBiffRecord
    {
        protected byte[] m_bytes;
        protected int m_readoffset;
        internal byte[] Bytes
        {
            get
            {
                return this.m_bytes;
            }
        }
        internal int Offset
        {
            get
            {
                return this.m_readoffset - 4;
            }
        }
        public BIFFRECORDTYPE ID
        {
            get
            {
                return (BIFFRECORDTYPE)BitConverter.ToUInt16(this.m_bytes, this.m_readoffset - 4);
            }
        }
        public ushort RecordSize
        {
            get
            {
                return BitConverter.ToUInt16(this.m_bytes, this.m_readoffset - 2);
            }
        }
        public int Size
        {
            get
            {
                return (int)(4 + this.RecordSize);
            }
        }
        protected XlsBiffRecord(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        protected XlsBiffRecord(byte[] bytes, uint offset)
        {
            if ((long)bytes.Length - (long)((ulong)offset) < 4L)
            {
                throw new InvalidDataException("Oops! Buffer size is less than minimum BIFF record size");
            }
            this.m_bytes = bytes;
            this.m_readoffset = (int)(4u + offset);
            if ((long)bytes.Length < (long)((ulong)offset + (ulong)((long)this.Size)))
            {
                throw new InvalidDataException("Oops! Buffer size is less than entry length.");
            }
        }
        public static XlsBiffRecord GetRecord(byte[] bytes, uint offset)
        {
            uint num = (uint)BitConverter.ToUInt16(bytes, (int)offset);
            BIFFRECORDTYPE bIFFRECORDTYPE = (BIFFRECORDTYPE)num;
            XlsBiffRecord result;
            if (bIFFRECORDTYPE <= BIFFRECORDTYPE.BOOKBOOL)
            {
                if (bIFFRECORDTYPE <= BIFFRECORDTYPE.BOUNDSHEET)
                {
                    if (bIFFRECORDTYPE <= BIFFRECORDTYPE.RECORD1904)
                    {
                        switch (bIFFRECORDTYPE)
                        {
                            case BIFFRECORDTYPE.BLANK_OLD:
                                goto IL_205;
                            case BIFFRECORDTYPE.INTEGER_OLD:
                                goto IL_239;
                            case BIFFRECORDTYPE.NUMBER_OLD:
                                goto IL_246;
                            case BIFFRECORDTYPE.LABEL_OLD:
                                goto IL_21F;
                            case BIFFRECORDTYPE.BOOLERR_OLD:
                            case (BIFFRECORDTYPE)7:
                            case (BIFFRECORDTYPE)8:
                                goto IL_2F2;
                            case BIFFRECORDTYPE.FORMULA_OLD:
                                goto IL_26D;
                            case BIFFRECORDTYPE.BOF_V2:
                                break;
                            case BIFFRECORDTYPE.EOF:
                                result = new XlsBiffEOF(bytes, offset);
                                return result;
                            default:
                                if (bIFFRECORDTYPE != BIFFRECORDTYPE.RECORD1904)
                                {
                                    goto IL_2F2;
                                }
                                result = new XlsBiffSimpleValueRecord(bytes, offset);
                                return result;
                        }
                    }
                    else
                    {
                        switch (bIFFRECORDTYPE)
                        {
                            case BIFFRECORDTYPE.CONTINUE:
                                result = new XlsBiffContinue(bytes, offset);
                                return result;
                            case BIFFRECORDTYPE.WINDOW1:
                                result = new XlsBiffWindow1(bytes, offset);
                                return result;
                            case (BIFFRECORDTYPE)62:
                            case (BIFFRECORDTYPE)63:
                            case (BIFFRECORDTYPE)65:
                                goto IL_2F2;
                            case BIFFRECORDTYPE.BACKUP:
                                result = new XlsBiffSimpleValueRecord(bytes, offset);
                                return result;
                            case BIFFRECORDTYPE.CODEPAGE:
                                result = new XlsBiffSimpleValueRecord(bytes, offset);
                                return result;
                            default:
                                if (bIFFRECORDTYPE != BIFFRECORDTYPE.BOUNDSHEET)
                                {
                                    goto IL_2F2;
                                }
                                result = new XlsBiffBoundSheet(bytes, offset);
                                return result;
                        }
                    }
                }
                else
                {
                    if (bIFFRECORDTYPE <= BIFFRECORDTYPE.FNGROUPCOUNT)
                    {
                        if (bIFFRECORDTYPE == BIFFRECORDTYPE.HIDEOBJ)
                        {
                            result = new XlsBiffSimpleValueRecord(bytes, offset);
                            return result;
                        }
                        if (bIFFRECORDTYPE != BIFFRECORDTYPE.FNGROUPCOUNT)
                        {
                            goto IL_2F2;
                        }
                        result = new XlsBiffSimpleValueRecord(bytes, offset);
                        return result;
                    }
                    else
                    {
                        switch (bIFFRECORDTYPE)
                        {
                            case BIFFRECORDTYPE.MULRK:
                                result = new XlsBiffMulRKCell(bytes, offset);
                                return result;
                            case BIFFRECORDTYPE.MULBLANK:
                                result = new XlsBiffMulBlankCell(bytes, offset);
                                return result;
                            default:
                                switch (bIFFRECORDTYPE)
                                {
                                    case BIFFRECORDTYPE.RSTRING:
                                        goto IL_21F;
                                    case BIFFRECORDTYPE.DBCELL:
                                        result = new XlsBiffDbCell(bytes, offset);
                                        return result;
                                    case (BIFFRECORDTYPE)216:
                                    case (BIFFRECORDTYPE)217:
                                        goto IL_2F2;
                                    case BIFFRECORDTYPE.BOOKBOOL:
                                        result = new XlsBiffSimpleValueRecord(bytes, offset);
                                        return result;
                                    default:
                                        goto IL_2F2;
                                }
                                break;
                        }
                    }
                }
            }
            else
            {
                if (bIFFRECORDTYPE <= BIFFRECORDTYPE.INDEX)
                {
                    if (bIFFRECORDTYPE <= BIFFRECORDTYPE.LABELSST)
                    {
                        if (bIFFRECORDTYPE == BIFFRECORDTYPE.INTERFACEHDR)
                        {
                            result = new XlsBiffInterfaceHdr(bytes, offset);
                            return result;
                        }
                        switch (bIFFRECORDTYPE)
                        {
                            case BIFFRECORDTYPE.SST:
                                result = new XlsBiffSST(bytes, offset);
                                return result;
                            case BIFFRECORDTYPE.LABELSST:
                                result = new XlsBiffLabelSSTCell(bytes, offset);
                                return result;
                            default:
                                goto IL_2F2;
                        }
                    }
                    else
                    {
                        if (bIFFRECORDTYPE == BIFFRECORDTYPE.USESELFS)
                        {
                            result = new XlsBiffSimpleValueRecord(bytes, offset);
                            return result;
                        }
                        switch (bIFFRECORDTYPE)
                        {
                            case BIFFRECORDTYPE.DIMENSIONS:
                                result = new XlsBiffDimensions(bytes, offset);
                                return result;
                            case BIFFRECORDTYPE.BLANK:
                                goto IL_205;
                            case BIFFRECORDTYPE.INTEGER:
                                goto IL_239;
                            case BIFFRECORDTYPE.NUMBER:
                                goto IL_246;
                            case BIFFRECORDTYPE.LABEL:
                                goto IL_21F;
                            case BIFFRECORDTYPE.BOOLERR:
                            case (BIFFRECORDTYPE)518:
                            case (BIFFRECORDTYPE)522:
                                goto IL_2F2;
                            case BIFFRECORDTYPE.STRING:
                                result = new XlsBiffFormulaString(bytes, offset);
                                return result;
                            case BIFFRECORDTYPE.ROW:
                                result = new XlsBiffRow(bytes, offset);
                                return result;
                            case BIFFRECORDTYPE.BOF_V3:
                                break;
                            case BIFFRECORDTYPE.INDEX:
                                result = new XlsBiffIndex(bytes, offset);
                                return result;
                            default:
                                goto IL_2F2;
                        }
                    }
                }
                else
                {
                    if (bIFFRECORDTYPE <= BIFFRECORDTYPE.FORMULA)
                    {
                        if (bIFFRECORDTYPE == BIFFRECORDTYPE.RK)
                        {
                            result = new XlsBiffRKCell(bytes, offset);
                            return result;
                        }
                        if (bIFFRECORDTYPE != BIFFRECORDTYPE.FORMULA)
                        {
                            goto IL_2F2;
                        }
                        goto IL_26D;
                    }
                    else
                    {
                        if (bIFFRECORDTYPE != BIFFRECORDTYPE.BOF_V4 && bIFFRECORDTYPE != BIFFRECORDTYPE.BOF)
                        {
                            goto IL_2F2;
                        }
                    }
                }
            }
            result = new XlsBiffBOF(bytes, offset);
            return result;
        IL_205:
            result = new XlsBiffBlankCell(bytes, offset);
            return result;
        IL_21F:
            result = new XlsBiffLabelCell(bytes, offset);
            return result;
        IL_239:
            result = new XlsBiffIntegerCell(bytes, offset);
            return result;
        IL_246:
            result = new XlsBiffNumberCell(bytes, offset);
            return result;
        IL_26D:
            result = new XlsBiffFormulaCell(bytes, offset);
            return result;
        IL_2F2:
            result = new XlsBiffRecord(bytes, offset);
            return result;
        }
        public byte ReadByte(int offset)
        {
            return Buffer.GetByte(this.m_bytes, this.m_readoffset + offset);
        }
        public ushort ReadUInt16(int offset)
        {
            return BitConverter.ToUInt16(this.m_bytes, this.m_readoffset + offset);
        }
        public uint ReadUInt32(int offset)
        {
            return BitConverter.ToUInt32(this.m_bytes, this.m_readoffset + offset);
        }
        public ulong ReadUInt64(int offset)
        {
            return BitConverter.ToUInt64(this.m_bytes, this.m_readoffset + offset);
        }
        public short ReadInt16(int offset)
        {
            return BitConverter.ToInt16(this.m_bytes, this.m_readoffset + offset);
        }
        public int ReadInt32(int offset)
        {
            return BitConverter.ToInt32(this.m_bytes, this.m_readoffset + offset);
        }
        public long ReadInt64(int offset)
        {
            return BitConverter.ToInt64(this.m_bytes, this.m_readoffset + offset);
        }
        public byte[] ReadArray(int offset, int size)
        {
            byte[] array = new byte[size];
            Buffer.BlockCopy(this.m_bytes, this.m_readoffset + offset, array, 0, size);
            return array;
        }
        public float ReadFloat(int offset)
        {
            return BitConverter.ToSingle(this.m_bytes, this.m_readoffset + offset);
        }
        public double ReadDouble(int offset)
        {
            return BitConverter.ToDouble(this.m_bytes, this.m_readoffset + offset);
        }
    }
    internal class XlsBiffRKCell : XlsBiffBlankCell
    {
        public double Value
        {
            get
            {
                return XlsBiffRKCell.NumFromRK(base.ReadUInt32(6));
            }
        }
        internal XlsBiffRKCell(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        internal XlsBiffRKCell(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        public static double NumFromRK(uint rk)
        {
            double num;
            if ((rk & 2u) == 2u)
            {
                num = (double)(rk >> 2);
            }
            else
            {
                num = BitConverter.Int64BitsToDouble((long)((long)((ulong)(rk & 4294967292u)) << 32));
            }
            if ((rk & 1u) == 1u)
            {
                num /= 100.0;
            }
            return num;
        }
    }
    internal class XlsBiffRow : XlsBiffRecord
    {
        public ushort RowIndex
        {
            get
            {
                return base.ReadUInt16(0);
            }
        }
        public ushort FirstDefinedColumn
        {
            get
            {
                return base.ReadUInt16(2);
            }
        }
        public ushort LastDefinedColumn
        {
            get
            {
                return base.ReadUInt16(4);
            }
        }
        public uint RowHeight
        {
            get
            {
                return (uint)base.ReadUInt16(6);
            }
        }
        public ushort Flags
        {
            get
            {
                return base.ReadUInt16(12);
            }
        }
        public ushort XFormat
        {
            get
            {
                return base.ReadUInt16(14);
            }
        }
        internal XlsBiffRow(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffRow(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffSimpleValueRecord : XlsBiffRecord
    {
        public ushort Value
        {
            get
            {
                return base.ReadUInt16(0);
            }
        }
        internal XlsBiffSimpleValueRecord(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffSimpleValueRecord(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsBiffSST : XlsBiffRecord
    {
        private List<string> m_strings;
        private uint m_size = 0u;
        private List<uint> continues = new List<uint>();
        public uint Count
        {
            get
            {
                return base.ReadUInt32(0);
            }
        }
        public uint UniqueCount
        {
            get
            {
                return base.ReadUInt32(4);
            }
        }
        internal XlsBiffSST(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
            this.m_size = (uint)base.RecordSize;
            this.m_strings = new List<string>((int)this.Count);
        }
        internal XlsBiffSST(byte[] bytes)
            : this(bytes, 0u)
        {
        }
        public void ReadStrings()
        {
            uint num = (uint)(this.m_readoffset + 8);
            uint num2 = (uint)(this.m_readoffset + (int)base.RecordSize);
            int num3 = 0;
            uint num4 = this.UniqueCount;
            while (num < num2)
            {
                XlsFormattedUnicodeString xlsFormattedUnicodeString = new XlsFormattedUnicodeString(this.m_bytes, num);
                uint headSize = xlsFormattedUnicodeString.HeadSize;
                uint tailSize = xlsFormattedUnicodeString.TailSize;
                uint num5 = (uint)xlsFormattedUnicodeString.CharacterCount;
                uint num6 = headSize + tailSize + num5 + (xlsFormattedUnicodeString.IsMultiByte ? num5 : 0u);
                if (num + num6 > num2)
                {
                    if (num3 >= this.continues.Count)
                    {
                        break;
                    }
                    uint num7 = this.continues[num3];
                    byte @byte = Buffer.GetByte(this.m_bytes, (int)(num7 + 4u));
                    byte[] array = new byte[num6 * 2u];
                    Buffer.BlockCopy(this.m_bytes, (int)num, array, 0, (int)(num2 - num));
                    if (@byte == 0 && xlsFormattedUnicodeString.IsMultiByte)
                    {
                        num5 -= (num2 - headSize - num) / 2u;
                        string @string = Encoding.Default.GetString(this.m_bytes, (int)(num7 + 5u), (int)num5);
                        byte[] bytes = Encoding.Unicode.GetBytes(@string);
                        Buffer.BlockCopy(bytes, 0, array, (int)(num2 - num), bytes.Length);
                        Buffer.BlockCopy(this.m_bytes, (int)(num7 + 5u + num5), array, (int)(num2 - num + num5 + num5), (int)tailSize);
                        num = num7 + 5u + num5 + tailSize;
                    }
                    else
                    {
                        if (@byte == 1 && !xlsFormattedUnicodeString.IsMultiByte)
                        {
                            num5 -= num2 - num - headSize;
                            string @string = Encoding.Unicode.GetString(this.m_bytes, (int)(num7 + 5u), (int)(num5 + num5));
                            byte[] bytes = Encoding.Default.GetBytes(@string);
                            Buffer.BlockCopy(bytes, 0, array, (int)(num2 - num), bytes.Length);
                            Buffer.BlockCopy(this.m_bytes, (int)(num7 + 5u + num5 + num5), array, (int)(num2 - num + num5), (int)tailSize);
                            num = num7 + 5u + num5 + num5 + tailSize;
                        }
                        else
                        {
                            Buffer.BlockCopy(this.m_bytes, (int)(num7 + 5u), array, (int)(num2 - num), (int)(num6 - num2 + num));
                            num = num7 + 5u + num6 - num2 + num;
                        }
                    }
                    num2 = num7 + 4u + (uint)BitConverter.ToUInt16(this.m_bytes, (int)(num7 + 2u));
                    num3++;
                    xlsFormattedUnicodeString = new XlsFormattedUnicodeString(array, 0u);
                }
                else
                {
                    num += num6;
                    if (num == num2)
                    {
                        if (num3 < this.continues.Count)
                        {
                            uint num7 = this.continues[num3];
                            num = num7 + 4u;
                            num2 = num + (uint)BitConverter.ToUInt16(this.m_bytes, (int)(num7 + 2u));
                            num3++;
                        }
                        else
                        {
                            num4 = 1u;
                        }
                    }
                }
                this.m_strings.Add(xlsFormattedUnicodeString.Value);
                num4 -= 1u;
                if (num4 == 0u)
                {
                    break;
                }
            }
        }
        public string GetString(uint SSTIndex)
        {
            string result;
            if ((ulong)SSTIndex < (ulong)((long)this.m_strings.Count))
            {
                result = this.m_strings[(int)SSTIndex];
            }
            else
            {
                result = "NOT FOUND #" + SSTIndex.ToString();
            }
            return result;
        }
        public void Append(XlsBiffContinue fragment)
        {
            this.continues.Add((uint)fragment.Offset);
            this.m_size += (uint)fragment.Size;
        }
    }
    internal class XlsBiffStream : XlsStream
    {
        private byte[] bytes;
        private int m_offset;
        private int m_size;
        public int Size
        {
            get
            {
                return this.m_size;
            }
        }
        public int Position
        {
            get
            {
                return this.m_offset;
            }
        }
        public XlsBiffStream(XlsHeader hdr, uint streamStart)
            : base(hdr, streamStart)
        {
            this.bytes = base.ReadStream();
            this.m_size = this.bytes.Length;
            this.m_offset = 0;
        }
        [Obsolete("Use BIFF-specific methods for this stream")]
        public new byte[] ReadStream()
        {
            return this.bytes;
        }
        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Seek(int offset, SeekOrigin origin)
        {
            switch (origin)
            {
                case SeekOrigin.Begin:
                    this.m_offset = offset;
                    break;
                case SeekOrigin.Current:
                    this.m_offset += offset;
                    break;
                case SeekOrigin.End:
                    this.m_offset = this.m_size - offset;
                    break;
            }
            if (this.m_offset < 0)
            {
                throw new IndexOutOfRangeException("Oops! Moving before stream start");
            }
            if (this.m_offset > this.m_size)
            {
                throw new IndexOutOfRangeException("Oops! Moving after stream end");
            }
        }
        [MethodImpl(MethodImplOptions.Synchronized)]
        public XlsBiffRecord Read()
        {
            XlsBiffRecord record = XlsBiffRecord.GetRecord(this.bytes, (uint)this.m_offset);
            this.m_offset += record.Size;
            XlsBiffRecord result;
            if (this.m_offset > this.m_size)
            {
                result = null;
            }
            else
            {
                result = record;
            }
            return result;
        }
        public XlsBiffRecord ReadAt(int offset)
        {
            XlsBiffRecord record = XlsBiffRecord.GetRecord(this.bytes, (uint)offset);
            XlsBiffRecord result;
            if (this.m_offset + record.Size > this.m_size)
            {
                result = null;
            }
            else
            {
                result = record;
            }
            return result;
        }
    }
    internal class XlsBiffWindow1 : XlsBiffRecord
    {
        [Flags]
        public enum Window1Flags : ushort
        {
            Hidden = 1,
            Minimized = 2,
            HScrollVisible = 8,
            VScrollVisible = 16,
            WorkbookTabs = 32
        }
        public ushort Left
        {
            get
            {
                return base.ReadUInt16(0);
            }
        }
        public ushort Top
        {
            get
            {
                return base.ReadUInt16(2);
            }
        }
        public ushort Width
        {
            get
            {
                return base.ReadUInt16(4);
            }
        }
        public ushort Height
        {
            get
            {
                return base.ReadUInt16(6);
            }
        }
        public XlsBiffWindow1.Window1Flags Flags
        {
            get
            {
                return (XlsBiffWindow1.Window1Flags)base.ReadUInt16(8);
            }
        }
        public ushort ActiveTab
        {
            get
            {
                return base.ReadUInt16(10);
            }
        }
        public ushort FirstVisibleTab
        {
            get
            {
                return base.ReadUInt16(12);
            }
        }
        public ushort SelectedTabCount
        {
            get
            {
                return base.ReadUInt16(14);
            }
        }
        public ushort TabRatio
        {
            get
            {
                return base.ReadUInt16(16);
            }
        }
        internal XlsBiffWindow1(byte[] bytes, uint offset)
            : base(bytes, offset)
        {
        }
        internal XlsBiffWindow1(byte[] bytes)
            : this(bytes, 0u)
        {
        }
    }
    internal class XlsDirectoryEntry
    {
        public const int Length = 128;
        private byte[] m_bytes;
        private XlsDirectoryEntry m_leftSibling = null;
        private XlsDirectoryEntry m_rightSibling = null;
        private XlsDirectoryEntry m_child = null;
        public string EntryName
        {
            get
            {
                string arg_20_0 = Encoding.Unicode.GetString(this.m_bytes, 0, (int)this.EntryLength);
                char[] trimChars = new char[1];
                return arg_20_0.TrimEnd(trimChars);
            }
        }
        public ushort EntryLength
        {
            get
            {
                return BitConverter.ToUInt16(this.m_bytes, 64);
            }
        }
        public STGTY EntryType
        {
            get
            {
                return (STGTY)Buffer.GetByte(this.m_bytes, 66);
            }
        }
        public DECOLOR EntryColor
        {
            get
            {
                return (DECOLOR)Buffer.GetByte(this.m_bytes, 67);
            }
        }
        public uint LeftSiblingSid
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 68);
            }
        }
        public XlsDirectoryEntry LeftSibling
        {
            get
            {
                return this.m_leftSibling;
            }
            set
            {
                if (this.m_leftSibling == null)
                {
                    this.m_leftSibling = value;
                }
            }
        }
        public uint RightSiblingSid
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 72);
            }
        }
        public XlsDirectoryEntry RightSibling
        {
            get
            {
                return this.m_rightSibling;
            }
            set
            {
                if (this.m_rightSibling == null)
                {
                    this.m_rightSibling = value;
                }
            }
        }
        public uint ChildSid
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 76);
            }
        }
        public XlsDirectoryEntry Child
        {
            get
            {
                return this.m_child;
            }
            set
            {
                if (this.m_child == null)
                {
                    this.m_child = value;
                }
            }
        }
        public Guid ClassId
        {
            get
            {
                byte[] array = new byte[16];
                Buffer.BlockCopy(this.m_bytes, 80, array, 0, 16);
                return new Guid(array);
            }
        }
        public uint UserFlags
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 96);
            }
        }
        public DateTime CreationTime
        {
            get
            {
                return DateTime.FromFileTime(BitConverter.ToInt64(this.m_bytes, 100));
            }
        }
        public DateTime LastWriteTime
        {
            get
            {
                return DateTime.FromFileTime(BitConverter.ToInt64(this.m_bytes, 108));
            }
        }
        public uint StreamFirstSector
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 116);
            }
        }
        public uint StreamSize
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 120);
            }
        }
        public uint PropType
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 124);
            }
        }
        public XlsDirectoryEntry(byte[] bytes)
        {
            if (bytes.Length < 128)
            {
                throw new InvalidDataException("Oops! Array is too small.");
            }
            this.m_bytes = bytes;
        }
    }
    internal class XlsFat
    {
        private List<uint> m_fat;
        private int m_sectors_for_fat;
        private int m_sectors;
        private XlsHeader m_hdr;
        public int SectorsForFat
        {
            get
            {
                return this.m_sectors_for_fat;
            }
        }
        public int SectorsCount
        {
            get
            {
                return this.m_sectors;
            }
        }
        public XlsHeader Header
        {
            get
            {
                return this.m_hdr;
            }
        }
        public XlsFat(XlsHeader hdr, List<uint> sectors)
        {
            this.m_hdr = hdr;
            this.m_sectors_for_fat = sectors.Count;
            uint num = 0u;
            int sectorSize = hdr.SectorSize;
            byte[] buffer = new byte[sectorSize];
            Stream fileStream = hdr.FileStream;
            using (MemoryStream memoryStream = new MemoryStream(sectorSize * this.m_sectors_for_fat))
            {
                Stream obj;
                Monitor.Enter(obj = fileStream);
                try
                {
                    for (int i = 0; i < sectors.Count; i++)
                    {
                        uint num2 = sectors[i];
                        if (num == 0u || num2 - num != 1u)
                        {
                            fileStream.Seek((long)((ulong)(num2 + 1u) * (ulong)((long)sectorSize)), SeekOrigin.Begin);
                        }
                        num = num2;
                        fileStream.Read(buffer, 0, sectorSize);
                        memoryStream.Write(buffer, 0, sectorSize);
                    }
                }
                finally
                {
                    Monitor.Exit(obj);
                }
                memoryStream.Seek(0L, SeekOrigin.Begin);
                BinaryReader binaryReader = new BinaryReader(memoryStream);
                this.m_sectors = (int)memoryStream.Length / 4;
                this.m_fat = new List<uint>(this.m_sectors);
                for (int i = 0; i < this.m_sectors; i++)
                {
                    this.m_fat.Add(binaryReader.ReadUInt32());
                }
                binaryReader.Close();
                memoryStream.Close();
            }
        }
        public uint GetNextSector(uint sector)
        {
            if ((long)this.m_fat.Count <= (long)((ulong)sector))
            {
                throw new ArgumentOutOfRangeException("Oops! There's no such sector in FAT.");
            }
            uint num = this.m_fat[(int)sector];
            if (num == 4294967293u || num == 4294967292u)
            {
                throw new InvalidOperationException("Oops! Trying to read stream from FAT area.");
            }
            return num;
        }
    }
    internal class XlsFormattedUnicodeString
    {
        [Flags]
        public enum FormattedUnicodeStringFlags : byte
        {
            MultiByte = 1,
            HasExtendedString = 4,
            HasFormatting = 8
        }
        protected byte[] m_bytes;
        protected uint m_offset;
        public ushort CharacterCount
        {
            get
            {
                return BitConverter.ToUInt16(this.m_bytes, (int)this.m_offset);
            }
        }
        public XlsFormattedUnicodeString.FormattedUnicodeStringFlags Flags
        {
            get
            {
                return (XlsFormattedUnicodeString.FormattedUnicodeStringFlags)Buffer.GetByte(this.m_bytes, (int)(this.m_offset + 2u));
            }
        }
        public bool HasExtString
        {
            get
            {
                return false;
            }
        }
        public bool HasFormatting
        {
            get
            {
                return (byte)(this.Flags & XlsFormattedUnicodeString.FormattedUnicodeStringFlags.HasFormatting) == 8;
            }
        }
        public bool IsMultiByte
        {
            get
            {
                return (byte)(this.Flags & XlsFormattedUnicodeString.FormattedUnicodeStringFlags.MultiByte) == 1;
            }
        }
        private uint ByteCount
        {
            get
            {
                return (uint)(this.CharacterCount * (this.IsMultiByte ? 2 : 1));
            }
        }
        public ushort FormatCount
        {
            get
            {
                return this.HasFormatting ? BitConverter.ToUInt16(this.m_bytes, (int)(this.m_offset + 3u)) : (ushort)0;
            }
        }
        public uint ExtendedStringSize
        {
            get
            {
                return (uint)(this.HasExtString ? BitConverter.ToUInt16(this.m_bytes, (int)(this.m_offset + (this.HasFormatting ? 5u : 3u))) : 0);
            }
        }
        public uint HeadSize
        {
            get
            {
                return (this.HasFormatting ? 2u : 0u) + (this.HasExtString ? 4u : 0u) + 3u;
            }
        }
        public uint TailSize
        {
            get
            {
                return (uint)(this.HasFormatting ? (4 * this.FormatCount) : 0) + (this.HasExtString ? this.ExtendedStringSize : 0u);
            }
        }
        public uint Size
        {
            get
            {
                uint num = (uint)(this.HasFormatting ? (2 + this.FormatCount * 4) : 0) + (this.HasExtString ? (4u + this.ExtendedStringSize) : 0u) + 3u;
                uint result;
                if (!this.IsMultiByte)
                {
                    result = num + (uint)this.CharacterCount;
                }
                else
                {
                    result = num + (uint)(this.CharacterCount * 2);
                }
                return result;
            }
        }
        public string Value
        {
            get
            {
                string @string;
                if (this.IsMultiByte)
                {
                    @string = Encoding.Unicode.GetString(this.m_bytes, (int)(this.m_offset + this.HeadSize), (int)this.ByteCount);
                }
                else
                {
                    @string = Encoding.Default.GetString(this.m_bytes, (int)(this.m_offset + this.HeadSize), (int)this.ByteCount);
                }
                return @string;
            }
        }
        public XlsFormattedUnicodeString(byte[] bytes, uint offset)
        {
            this.m_bytes = bytes;
            this.m_offset = offset;
        }
    }
    internal class XlsHeader
    {
        private byte[] m_bytes;
        private Stream m_file;
        private XlsFat m_fat = null;
        public ulong Signature
        {
            get
            {
                return BitConverter.ToUInt64(this.m_bytes, 0);
            }
        }
        public bool IsSignatureValid
        {
            get
            {
                return this.Signature == 16220472316735377360uL;
            }
        }
        public Guid ClassId
        {
            get
            {
                byte[] array = new byte[16];
                Buffer.BlockCopy(this.m_bytes, 8, array, 0, 16);
                return new Guid(array);
            }
        }
        public ushort Version
        {
            get
            {
                return BitConverter.ToUInt16(this.m_bytes, 24);
            }
        }
        public ushort DllVersion
        {
            get
            {
                return BitConverter.ToUInt16(this.m_bytes, 26);
            }
        }
        public ushort ByteOrder
        {
            get
            {
                return BitConverter.ToUInt16(this.m_bytes, 28);
            }
        }
        public int SectorSize
        {
            get
            {
                return 1 << (int)BitConverter.ToUInt16(this.m_bytes, 30);
            }
        }
        public int MiniSectorSize
        {
            get
            {
                return 1 << (int)BitConverter.ToUInt16(this.m_bytes, 32);
            }
        }
        public int FatSectorCount
        {
            get
            {
                return BitConverter.ToInt32(this.m_bytes, 44);
            }
        }
        public uint RootDirectoryEntryStart
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 48);
            }
        }
        public uint TransactionSignature
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 52);
            }
        }
        public uint MiniStreamCutoff
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 56);
            }
        }
        public uint MiniFatFirstSector
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 60);
            }
        }
        public int MiniFatSectorCount
        {
            get
            {
                return BitConverter.ToInt32(this.m_bytes, 64);
            }
        }
        public uint DifFirstSector
        {
            get
            {
                return BitConverter.ToUInt32(this.m_bytes, 68);
            }
        }
        public int DifSectorCount
        {
            get
            {
                return BitConverter.ToInt32(this.m_bytes, 72);
            }
        }
        public Stream FileStream
        {
            get
            {
                return this.m_file;
            }
        }
        public XlsFat FAT
        {
            get
            {
                uint num;
                if (this.m_fat != null)
                {
                    return this.m_fat;
                }
                int sectorSize = this.SectorSize;
                List<uint> sectors = new List<uint>(this.FatSectorCount);
                int startIndex = 0x4c;
                while (startIndex < sectorSize)
                {
                    num = BitConverter.ToUInt32(this.m_bytes, startIndex);
                    if (num == uint.MaxValue)
                    {
                        goto Label_0190;
                    }
                    sectors.Add(num);
                    startIndex += 4;
                }
                int difSectorCount = this.DifSectorCount;
                if (difSectorCount != 0)
                {
                    lock (this.m_file)
                    {
                        uint difFirstSector = this.DifFirstSector;
                        byte[] buffer = new byte[sectorSize];
                        uint num6 = 0;
                        while (difSectorCount > 0)
                        {
                            sectors.Capacity += 0x80;
                            if ((num6 == 0) || ((difFirstSector - num6) != 1))
                            {
                                this.m_file.Seek((difFirstSector + 1) * sectorSize, SeekOrigin.Begin);
                            }
                            num6 = difFirstSector;
                            this.m_file.Read(buffer, 0, sectorSize);
                            for (startIndex = 0; startIndex < 0x1fc; startIndex += 4)
                            {
                                num = BitConverter.ToUInt32(buffer, startIndex);
                                if (num == uint.MaxValue)
                                {
                                    goto Label_0190;
                                }
                                sectors.Add(num);
                            }
                            num = BitConverter.ToUInt32(buffer, 0x1fc);
                            if (num == uint.MaxValue)
                            {
                                goto Label_0190;
                            }
                            if (difSectorCount-- > 1)
                            {
                                difFirstSector = num;
                            }
                            else
                            {
                                sectors.Add(num);
                            }
                        }
                    }
                }
            Label_0190:
                this.m_fat = new XlsFat(this, sectors);
                return this.m_fat;
            }
        }

        private XlsHeader(Stream file)
        {
            this.m_bytes = new byte[512];
            this.m_file = file;
        }
        public static XlsHeader ReadHeader(Stream file)
        {
            XlsHeader xlsHeader = new XlsHeader(file);
            Monitor.Enter(file);
            try
            {
                file.Seek(0L, SeekOrigin.Begin);
                file.Read(xlsHeader.m_bytes, 0, 512);
            }
            finally
            {
                Monitor.Exit(file);
            }
            if (!xlsHeader.IsSignatureValid)
            {
                throw new InvalidHeaderException("Invalid file signature");
            }
            if (xlsHeader.ByteOrder != 65534)
            {
                throw new FormatException("Invalid byte order specified");
            }
            return xlsHeader;
        }
    }
    internal class XlsRootDirectory
    {
        private XlsHeader m_hdr;
        private List<XlsDirectoryEntry> m_entries;
        private XlsDirectoryEntry m_root = null;
        public ReadOnlyCollection<XlsDirectoryEntry> Entries
        {
            get
            {
                return this.m_entries.AsReadOnly();
            }
        }
        public XlsDirectoryEntry RootEntry
        {
            get
            {
                return this.m_root;
            }
        }
        public XlsRootDirectory(XlsHeader hdr)
        {
            this.m_hdr = hdr;
            XlsStream xlsStream = new XlsStream(hdr, hdr.RootDirectoryEntryStart);
            byte[] array = xlsStream.ReadStream();
            List<XlsDirectoryEntry> list = new List<XlsDirectoryEntry>();
            for (int i = 0; i < array.Length; i += 128)
            {
                byte[] array2 = new byte[128];
                Buffer.BlockCopy(array, i, array2, 0, array2.Length);
                list.Add(new XlsDirectoryEntry(array2));
            }
            this.m_entries = list;
            for (int i = 0; i < list.Count; i++)
            {
                XlsDirectoryEntry xlsDirectoryEntry = list[i];
                if (this.m_root == null && xlsDirectoryEntry.EntryType == STGTY.STGTY_ROOT)
                {
                    this.m_root = xlsDirectoryEntry;
                }
                if (xlsDirectoryEntry.ChildSid != 4294967295u)
                {
                    xlsDirectoryEntry.Child = list[(int)xlsDirectoryEntry.ChildSid];
                }
                if (xlsDirectoryEntry.LeftSiblingSid != 4294967295u)
                {
                    xlsDirectoryEntry.LeftSibling = list[(int)xlsDirectoryEntry.LeftSiblingSid];
                }
                if (xlsDirectoryEntry.RightSiblingSid != 4294967295u)
                {
                    xlsDirectoryEntry.RightSibling = list[(int)xlsDirectoryEntry.RightSiblingSid];
                }
            }
        }
        public XlsDirectoryEntry FindEntry(string EntryName)
        {
            XlsDirectoryEntry result;
            foreach (XlsDirectoryEntry current in this.m_entries)
            {
                if (current.EntryName == EntryName)
                {
                    result = current;
                    return result;
                }
            }
            result = null;
            return result;
        }
        internal class XlsStream
        {
            protected Stream m_file;
            protected XlsFat m_fat;
            protected XlsHeader m_hdr;
            protected uint m_startSector;
            public uint BaseOffset
            {
                get
                {
                    return (uint)((ulong)(this.m_startSector + 1u) * (ulong)((long)this.m_hdr.SectorSize));
                }
            }
            public uint BaseSector
            {
                get
                {
                    return this.m_startSector;
                }
            }
            public XlsStream(XlsHeader hdr, uint startSector)
            {
                this.m_file = hdr.FileStream;
                this.m_fat = hdr.FAT;
                this.m_hdr = hdr;
                this.m_startSector = startSector;
            }
            public byte[] ReadStream()
            {
                uint num = this.m_startSector;
                uint num2 = 0u;
                int sectorSize = this.m_hdr.SectorSize;
                byte[] buffer = new byte[sectorSize];
                byte[] result;
                using (MemoryStream memoryStream = new MemoryStream(sectorSize * 8))
                {
                    Stream file;
                    Monitor.Enter(file = this.m_file);
                    try
                    {
                        do
                        {
                            if (num2 == 0u || num - num2 != 1u)
                            {
                                this.m_file.Seek((long)((ulong)(num + 1u) * (ulong)((long)sectorSize)), SeekOrigin.Begin);
                            }
                            num2 = num;
                            this.m_file.Read(buffer, 0, sectorSize);
                            memoryStream.Write(buffer, 0, sectorSize);
                        }
                        while ((num = this.m_fat.GetNextSector(num)) != 4294967294u);
                    }
                    finally
                    {
                        Monitor.Exit(file);
                    }
                    byte[] array = memoryStream.ToArray();
                    memoryStream.Close();
                    result = array;
                }
                return result;
            }
        }


    }
    internal class XlsStream
    {
        protected Stream m_file;
        protected XlsFat m_fat;
        protected XlsHeader m_hdr;
        protected uint m_startSector;
        public uint BaseOffset
        {
            get
            {
                return (uint)((ulong)(this.m_startSector + 1u) * (ulong)((long)this.m_hdr.SectorSize));
            }
        }
        public uint BaseSector
        {
            get
            {
                return this.m_startSector;
            }
        }
        public XlsStream(XlsHeader hdr, uint startSector)
        {
            this.m_file = hdr.FileStream;
            this.m_fat = hdr.FAT;
            this.m_hdr = hdr;
            this.m_startSector = startSector;
        }
        public byte[] ReadStream()
        {
            uint num = this.m_startSector;
            uint num2 = 0u;
            int sectorSize = this.m_hdr.SectorSize;
            byte[] buffer = new byte[sectorSize];
            byte[] result;
            using (MemoryStream memoryStream = new MemoryStream(sectorSize * 8))
            {
                Stream file;
                Monitor.Enter(file = this.m_file);
                try
                {
                    do
                    {
                        if (num2 == 0u || num - num2 != 1u)
                        {
                            this.m_file.Seek((long)((ulong)(num + 1u) * (ulong)((long)sectorSize)), SeekOrigin.Begin);
                        }
                        num2 = num;
                        this.m_file.Read(buffer, 0, sectorSize);
                        memoryStream.Write(buffer, 0, sectorSize);
                    }
                    while ((num = this.m_fat.GetNextSector(num)) != 4294967294u);
                }
                finally
                {
                    Monitor.Exit(file);
                }
                byte[] array = memoryStream.ToArray();
                memoryStream.Close();
                result = array;
            }
            return result;
        }
    }
    internal class XlsWorkbookGlobals
    {
        private XlsBiffInterfaceHdr m_InterfaceHdr = null;
        private XlsBiffRecord m_MMS = null;
        private XlsBiffRecord m_WriteAccess = null;
        private XlsBiffSimpleValueRecord m_CodePage = null;
        private XlsBiffRecord m_DSF = null;
        private XlsBiffRecord m_Country = null;
        private XlsBiffSimpleValueRecord m_Backup = null;
        private List<XlsBiffRecord> m_Fonts = new List<XlsBiffRecord>();
        private List<XlsBiffRecord> m_Formats = new List<XlsBiffRecord>();
        private List<XlsBiffRecord> m_ExtendedFormats = new List<XlsBiffRecord>();
        private List<XlsBiffRecord> m_Styles = new List<XlsBiffRecord>();
        private List<XlsBiffBoundSheet> m_Sheets = new List<XlsBiffBoundSheet>();
        private XlsBiffSST m_SST = null;
        private XlsBiffRecord m_ExtSST = null;
        public XlsBiffInterfaceHdr InterfaceHdr
        {
            get
            {
                return this.m_InterfaceHdr;
            }
            set
            {
                this.m_InterfaceHdr = value;
            }
        }
        public XlsBiffRecord MMS
        {
            get
            {
                return this.m_MMS;
            }
            set
            {
                this.m_MMS = value;
            }
        }
        public XlsBiffRecord WriteAccess
        {
            get
            {
                return this.m_WriteAccess;
            }
            set
            {
                this.m_WriteAccess = value;
            }
        }
        public XlsBiffSimpleValueRecord CodePage
        {
            get
            {
                return this.m_CodePage;
            }
            set
            {
                this.m_CodePage = value;
            }
        }
        public XlsBiffRecord DSF
        {
            get
            {
                return this.m_DSF;
            }
            set
            {
                this.m_DSF = value;
            }
        }
        public XlsBiffRecord Country
        {
            get
            {
                return this.m_Country;
            }
            set
            {
                this.m_Country = value;
            }
        }
        public XlsBiffSimpleValueRecord Backup
        {
            get
            {
                return this.m_Backup;
            }
            set
            {
                this.m_Backup = value;
            }
        }
        public List<XlsBiffRecord> Fonts
        {
            get
            {
                return this.m_Fonts;
            }
        }
        public List<XlsBiffRecord> Formats
        {
            get
            {
                return this.m_Formats;
            }
        }
        public List<XlsBiffRecord> ExtendedFormats
        {
            get
            {
                return this.m_ExtendedFormats;
            }
        }
        public List<XlsBiffRecord> Styles
        {
            get
            {
                return this.m_Styles;
            }
        }
        public List<XlsBiffBoundSheet> Sheets
        {
            get
            {
                return this.m_Sheets;
            }
        }
        public XlsBiffSST SST
        {
            get
            {
                return this.m_SST;
            }
            set
            {
                this.m_SST = value;
            }
        }
        public XlsBiffRecord ExtSST
        {
            get
            {
                return this.m_ExtSST;
            }
            set
            {
                this.m_ExtSST = value;
            }
        }
    }
    internal class XlsWorksheet
    {
        private int m_Index = 0;
        private string m_Name = string.Empty;
        private uint m_dataOffset = 0u;
        private DataTable m_Data = null;
        private XlsBiffSimpleValueRecord m_CalcMode = null;
        private XlsBiffSimpleValueRecord m_CalcCount = null;
        private XlsBiffSimpleValueRecord m_RefMode = null;
        private XlsBiffSimpleValueRecord m_Iteration = null;
        private XlsBiffRecord m_Delta = null;
        private XlsBiffDimensions m_Dimensions = null;
        private XlsBiffRecord m_Window2 = null;
        public string Name
        {
            get
            {
                return this.m_Name;
            }
        }
        public int Index
        {
            get
            {
                return this.m_Index;
            }
        }
        public uint DataOffset
        {
            get
            {
                return this.m_dataOffset;
            }
        }
        public DataTable Data
        {
            get
            {
                return this.m_Data;
            }
            set
            {
                this.m_Data = value;
            }
        }
        public XlsBiffSimpleValueRecord CalcMode
        {
            get
            {
                return this.m_CalcMode;
            }
            set
            {
                this.m_CalcMode = value;
            }
        }
        public XlsBiffSimpleValueRecord CalcCount
        {
            get
            {
                return this.m_CalcCount;
            }
            set
            {
                this.m_CalcCount = value;
            }
        }
        public XlsBiffSimpleValueRecord RefMode
        {
            get
            {
                return this.m_RefMode;
            }
            set
            {
                this.m_RefMode = value;
            }
        }
        public XlsBiffSimpleValueRecord Iteration
        {
            get
            {
                return this.m_Iteration;
            }
            set
            {
                this.m_Iteration = value;
            }
        }
        public XlsBiffRecord Delta
        {
            get
            {
                return this.m_Delta;
            }
            set
            {
                this.m_Delta = value;
            }
        }
        public XlsBiffDimensions Dimensions
        {
            get
            {
                return this.m_Dimensions;
            }
            set
            {
                this.m_Dimensions = value;
            }
        }
        public XlsBiffRecord Window2
        {
            get
            {
                return this.m_Window2;
            }
            set
            {
                this.m_Window2 = value;
            }
        }
        public XlsWorksheet(int index, XlsBiffBoundSheet refSheet)
        {
            this.m_Index = index;
            this.m_Name = refSheet.SheetName;
            this.m_dataOffset = refSheet.StartOffset;
        }
    }
    #endregion

    public class ExcelDataReader
    {
        private Stream m_file = null;
        private XlsHeader m_hdr = null;
        private XlsBiffStream m_stream = null;
        private XlsWorkbookGlobals m_globals = null;
        private List<XlsWorksheet> m_sheets = new List<XlsWorksheet>();
        private DataSet m_workbookData = null;
        private ushort m_version = 1536;
        private Encoding m_encoding = Encoding.Default;
        private string m_FileName = "";
        public string FileName
        {
            get
            {
                return this.m_FileName;
            }
            set
            {
                this.m_FileName = value;
            }
        }
        public DataSet WorkbookData
        {
            get
            {
                return this.m_workbookData;
            }
        }
        public ExcelDataReader(string ExcelFile)
        {
            this.m_FileName = ExcelFile;
        }
        public ExcelDataReader(Stream file)
        {
            this.m_file = file;
            this.m_hdr = XlsHeader.ReadHeader(this.m_file);
            XlsRootDirectory xlsRootDirectory = new XlsRootDirectory(this.m_hdr);
            XlsDirectoryEntry xlsDirectoryEntry = xlsRootDirectory.FindEntry("Workbook");
            if (xlsDirectoryEntry == null)
            {
                xlsDirectoryEntry = xlsRootDirectory.FindEntry("Book");
            }
            if (xlsDirectoryEntry == null)
            {
                throw new FileNotFoundException("Oops! Neither stream 'Workbook' nor 'Book' was found in file");
            }
            if (xlsDirectoryEntry.EntryType != STGTY.STGTY_STREAM)
            {
                throw new FormatException("Oops! Workbook directory entry is not a Stream");
            }
            this.m_stream = new XlsBiffStream(this.m_hdr, xlsDirectoryEntry.StreamFirstSector);
            this.ReadWorkbookGlobals();
            GC.Collect();
            this.m_workbookData = new DataSet();
            for (int i = 0; i < this.m_sheets.Count; i++)
            {
                if (this.ReadWorksheet(this.m_sheets[i]))
                {
                    this.m_workbookData.Tables.Add(this.m_sheets[i].Data);
                }
            }
            this.m_globals.SST = null;
            this.m_globals = null;
            this.m_sheets = null;
            this.m_stream = null;
            this.m_hdr = null;
            GC.Collect();
        }
        private void ReadWorkbookGlobals()
        {
            this.m_globals = new XlsWorkbookGlobals();
            this.m_stream.Seek(0, SeekOrigin.Begin);
            XlsBiffRecord xlsBiffRecord = this.m_stream.Read();
            XlsBiffBOF xlsBiffBOF = xlsBiffRecord as XlsBiffBOF;
            if (xlsBiffBOF == null || xlsBiffBOF.Type != BIFFTYPE.WorkbookGlobals)
            {
                throw new InvalidDataException("Oops! Stream has invalid data");
            }
            this.m_version = xlsBiffBOF.Version;
            this.m_encoding = Encoding.Unicode;
            bool isV = this.m_version >= 1536;
            bool flag = false;
            while ((xlsBiffRecord = this.m_stream.Read()) != null)
            {
                BIFFRECORDTYPE iD = xlsBiffRecord.ID;
                if (iD <= BIFFRECORDTYPE.COUNTRY)
                {
                    if (iD <= BIFFRECORDTYPE.FONT)
                    {
                        if (iD == BIFFRECORDTYPE.EOF)
                        {
                            if (this.m_globals.SST != null)
                            {
                                this.m_globals.SST.ReadStrings();
                            }
                            break;
                        }
                        if (iD == BIFFRECORDTYPE.FORMAT_V23)
                        {
                            goto IL_282;
                        }
                        if (iD == BIFFRECORDTYPE.FONT)
                        {
                            goto IL_26B;
                        }
                    }
                    else
                    {
                        if (iD <= BIFFRECORDTYPE.XF_V2)
                        {
                            if (iD != BIFFRECORDTYPE.CONTINUE)
                            {
                                switch (iD)
                                {
                                    case BIFFRECORDTYPE.CODEPAGE:
                                        this.m_globals.CodePage = (XlsBiffSimpleValueRecord)xlsBiffRecord;
                                        this.m_encoding = Encoding.GetEncoding((int)this.m_globals.CodePage.Value);
                                        break;
                                    case BIFFRECORDTYPE.XF_V2:
                                        goto IL_299;
                                }
                            }
                            else
                            {
                                if (flag)
                                {
                                    XlsBiffContinue fragment = (XlsBiffContinue)xlsBiffRecord;
                                    this.m_globals.SST.Append(fragment);
                                }
                            }
                        }
                        else
                        {
                            if (iD != BIFFRECORDTYPE.BOUNDSHEET)
                            {
                                if (iD == BIFFRECORDTYPE.COUNTRY)
                                {
                                    this.m_globals.Country = xlsBiffRecord;
                                }
                            }
                            else
                            {
                                XlsBiffBoundSheet xlsBiffBoundSheet = (XlsBiffBoundSheet)xlsBiffRecord;
                                if (xlsBiffBoundSheet.Type == XlsBiffBoundSheet.SheetType.Worksheet)
                                {
                                    xlsBiffBoundSheet.IsV8 = isV;
                                    xlsBiffBoundSheet.UseEncoding = this.m_encoding;
                                    this.m_sheets.Add(new XlsWorksheet(this.m_globals.Sheets.Count, xlsBiffBoundSheet));
                                    this.m_globals.Sheets.Add(xlsBiffBoundSheet);
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (iD <= BIFFRECORDTYPE.EXTSST)
                    {
                        if (iD <= BIFFRECORDTYPE.INTERFACEHDR)
                        {
                            if (iD != BIFFRECORDTYPE.MMS)
                            {
                                switch (iD)
                                {
                                    case BIFFRECORDTYPE.XF:
                                        goto IL_299;
                                    case BIFFRECORDTYPE.INTERFACEHDR:
                                        this.m_globals.InterfaceHdr = (XlsBiffInterfaceHdr)xlsBiffRecord;
                                        break;
                                }
                            }
                            else
                            {
                                this.m_globals.MMS = xlsBiffRecord;
                            }
                        }
                        else
                        {
                            if (iD != BIFFRECORDTYPE.SST)
                            {
                                if (iD == BIFFRECORDTYPE.EXTSST)
                                {
                                    this.m_globals.ExtSST = xlsBiffRecord;
                                    flag = false;
                                }
                            }
                            else
                            {
                                this.m_globals.SST = (XlsBiffSST)xlsBiffRecord;
                                flag = true;
                            }
                        }
                    }
                    else
                    {
                        if (iD <= BIFFRECORDTYPE.XF_V3)
                        {
                            if (iD == BIFFRECORDTYPE.FONT_V34)
                            {
                                goto IL_26B;
                            }
                            if (iD == BIFFRECORDTYPE.XF_V3)
                            {
                                goto IL_299;
                            }
                        }
                        else
                        {
                            if (iD == BIFFRECORDTYPE.FORMAT)
                            {
                                goto IL_282;
                            }
                            if (iD == BIFFRECORDTYPE.XF_V4)
                            {
                                goto IL_299;
                            }
                        }
                    }
                }
                continue;
            IL_26B:
                this.m_globals.Fonts.Add(xlsBiffRecord);
                continue;
            IL_282:
                this.m_globals.Formats.Add(xlsBiffRecord);
                continue;
            IL_299:
                this.m_globals.ExtendedFormats.Add(xlsBiffRecord);
            }
        }
        private bool ReadWorksheet(XlsWorksheet sheet)
        {
            this.m_stream.Seek((int)sheet.DataOffset, SeekOrigin.Begin);
            XlsBiffBOF xlsBiffBOF = this.m_stream.Read() as XlsBiffBOF;
            bool result;
            if (xlsBiffBOF == null || xlsBiffBOF.Type != BIFFTYPE.Worksheet)
            {
                result = false;
            }
            else
            {
                XlsBiffIndex xlsBiffIndex = this.m_stream.Read() as XlsBiffIndex;
                bool isV = this.m_version >= 1536;
                if (xlsBiffIndex != null)
                {
                    xlsBiffIndex.IsV8 = isV;
                    DataTable dataTable = new DataTable(sheet.Name);
                    XlsBiffDimensions xlsBiffDimensions = null;
                    XlsBiffRecord xlsBiffRecord;
                    while (true)
                    {
                        xlsBiffRecord = this.m_stream.Read();
                        if (xlsBiffRecord.ID == BIFFRECORDTYPE.DIMENSIONS)
                        {
                            break;
                        }
                        if (xlsBiffRecord.ID == BIFFRECORDTYPE.ROW)
                        {
                            goto IL_D3;
                        }
                    }
                    xlsBiffDimensions = (XlsBiffDimensions)xlsBiffRecord;
                IL_D3:
                    int num = 256;
                    if (xlsBiffDimensions != null)
                    {
                        xlsBiffDimensions.IsV8 = isV;
                        num = (int)xlsBiffDimensions.LastColumn;
                        sheet.Dimensions = xlsBiffDimensions;
                    }
                    for (int i = 0; i < num; i++)
                    {
                        dataTable.Columns.Add("Column" + (i + 1).ToString(), typeof(string));
                    }
                    sheet.Data = dataTable;
                    uint lastExistingRow = xlsBiffIndex.LastExistingRow;
                    if (xlsBiffIndex.LastExistingRow <= xlsBiffIndex.FirstExistingRow)
                    {
                        result = true;
                    }
                    else
                    {
                        dataTable.BeginLoadData();
                        int i = 0;
                        while ((long)i <= (long)((ulong)lastExistingRow))
                        {
                            dataTable.Rows.Add(dataTable.NewRow());
                            i++;
                        }
                        uint[] dbCellAddresses = xlsBiffIndex.DbCellAddresses;
                        i = 0;
                        while (i < dbCellAddresses.Length)
                        {
                            XlsBiffDbCell xlsBiffDbCell = (XlsBiffDbCell)this.m_stream.ReadAt((int)dbCellAddresses[i]);
                            int num2 = xlsBiffDbCell.RowAddress;
                            XlsBiffRow xlsBiffRow;
                            do
                            {
                                xlsBiffRow = (this.m_stream.ReadAt(num2) as XlsBiffRow);
                                if (xlsBiffRow == null)
                                {
                                    break;
                                }
                                num2 += xlsBiffRow.Size;
                            }
                            while (xlsBiffRow != null);
                        IL_21B:
                            while (true)
                            {
                                XlsBiffRecord xlsBiffRecord2 = this.m_stream.ReadAt(num2);
                                num2 += xlsBiffRecord2.Size;
                                if (xlsBiffRecord2 is XlsBiffDbCell)
                                {
                                    break;
                                }
                                if (xlsBiffRecord2 is XlsBiffEOF)
                                {
                                    break;
                                }
                                XlsBiffBlankCell xlsBiffBlankCell = xlsBiffRecord2 as XlsBiffBlankCell;
                                if (xlsBiffBlankCell != null)
                                {
                                    if ((int)xlsBiffBlankCell.ColumnIndex < num)
                                    {
                                        if ((uint)xlsBiffBlankCell.RowIndex <= lastExistingRow)
                                        {
                                            BIFFRECORDTYPE iD = xlsBiffBlankCell.ID;
                                            if (iD <= BIFFRECORDTYPE.RSTRING)
                                            {
                                                switch (iD)
                                                {
                                                    case BIFFRECORDTYPE.BLANK_OLD:
                                                        break;
                                                    case BIFFRECORDTYPE.INTEGER_OLD:
                                                        goto IL_365;
                                                    case BIFFRECORDTYPE.NUMBER_OLD:
                                                        goto IL_39E;
                                                    case BIFFRECORDTYPE.LABEL_OLD:
                                                        goto IL_3D4;
                                                    case BIFFRECORDTYPE.BOOLERR_OLD:
                                                        break;
                                                    case BIFFRECORDTYPE.FORMULA_OLD:
                                                        goto IL_4E3;
                                                    default:
                                                        switch (iD)
                                                        {
                                                            case BIFFRECORDTYPE.MULRK:
                                                                for (ushort num3 = xlsBiffBlankCell.ColumnIndex; num3 <= ((XlsBiffMulRKCell)xlsBiffBlankCell).LastColumnIndex; num3 += 1)
                                                                {
                                                                    dataTable.Rows[(int)xlsBiffBlankCell.RowIndex][(int)num3] = this.FormatNumber(((XlsBiffMulRKCell)xlsBiffBlankCell).GetValue(num3));
                                                                }
                                                                break;
                                                            case BIFFRECORDTYPE.MULBLANK:
                                                                break;
                                                            default:
                                                                if (iD == BIFFRECORDTYPE.RSTRING)
                                                                {
                                                                    goto IL_3D4;
                                                                }
                                                                break;
                                                        }
                                                        break;
                                                }
                                            }
                                            else
                                            {
                                                if (iD <= BIFFRECORDTYPE.LABEL)
                                                {
                                                    if (iD != BIFFRECORDTYPE.LABELSST)
                                                    {
                                                        switch (iD)
                                                        {
                                                            case BIFFRECORDTYPE.INTEGER:
                                                                goto IL_365;
                                                            case BIFFRECORDTYPE.NUMBER:
                                                                goto IL_39E;
                                                            case BIFFRECORDTYPE.LABEL:
                                                                goto IL_3D4;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        string @string = this.m_globals.SST.GetString(((XlsBiffLabelSSTCell)xlsBiffBlankCell).SSTIndex);
                                                        dataTable.Rows[(int)xlsBiffBlankCell.RowIndex][(int)xlsBiffBlankCell.ColumnIndex] = @string;
                                                    }
                                                }
                                                else
                                                {
                                                    if (iD != BIFFRECORDTYPE.RK)
                                                    {
                                                        if (iD == BIFFRECORDTYPE.FORMULA)
                                                        {
                                                            goto IL_4E3;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        dataTable.Rows[(int)xlsBiffBlankCell.RowIndex][(int)xlsBiffBlankCell.ColumnIndex] = this.FormatNumber(((XlsBiffRKCell)xlsBiffBlankCell).Value);
                                                    }
                                                }
                                            }
                                            continue;
                                        IL_3D4:
                                            dataTable.Rows[(int)xlsBiffBlankCell.RowIndex][(int)xlsBiffBlankCell.ColumnIndex] = ((XlsBiffLabelCell)xlsBiffBlankCell).Value;
                                            continue;
                                        IL_39E:
                                            dataTable.Rows[(int)xlsBiffBlankCell.RowIndex][(int)xlsBiffBlankCell.ColumnIndex] = this.FormatNumber(((XlsBiffNumberCell)xlsBiffBlankCell).Value);
                                            continue;
                                        IL_365:
                                            dataTable.Rows[(int)xlsBiffBlankCell.RowIndex][(int)xlsBiffBlankCell.ColumnIndex] = ((XlsBiffIntegerCell)xlsBiffBlankCell).Value.ToString();
                                            continue;
                                        IL_4E3:
                                            ((XlsBiffFormulaCell)xlsBiffBlankCell).UseEncoding = this.m_encoding;
                                            object obj = ((XlsBiffFormulaCell)xlsBiffBlankCell).Value;
                                            if (obj == null)
                                            {
                                                obj = string.Empty;
                                            }
                                            else
                                            {
                                                if (obj is FORMULAERROR)
                                                {
                                                    obj = "#" + ((FORMULAERROR)obj).ToString();
                                                }
                                                else
                                                {
                                                    if (obj is double)
                                                    {
                                                        obj = this.FormatNumber((double)obj);
                                                    }
                                                }
                                            }
                                            dataTable.Rows[(int)xlsBiffBlankCell.RowIndex][(int)xlsBiffBlankCell.ColumnIndex] = obj.ToString();
                                        }
                                    }
                                }
                            }
                        IL_5A2:
                            i++;
                            continue;
                            goto IL_5A2;
                            goto IL_21B;
                        }
                        dataTable.EndLoadData();
                        result = true;
                    }
                }
                else
                {
                    result = false;
                }
            }
            return result;
        }
        private string FormatNumber(double x)
        {
            string result;
            if (Math.Floor(x) == x)
            {
                result = Math.Floor(x).ToString();
            }
            else
            {
                result = Math.Round(x, 2).ToString(CultureInfo.InvariantCulture);
            }
            return result;
        }
        public static ExcelDataReader Read(string FileName, ComboBox cboSheet)
        {
            ExcelDataReader excelDataReader = null;
            ExcelDataReader result;
            try
            {
                FileStream fileStream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                excelDataReader = new ExcelDataReader(fileStream);
                fileStream.Close();
                cboSheet.Items.Clear();
                cboSheet.DisplayMember = "TableName";
                foreach (DataTable item in excelDataReader.WorkbookData.Tables)
                {
                    cboSheet.Items.Add(item);
                }
                if (cboSheet.Items.Count == 0)
                {
                    result = null;
                    return result;
                }
                cboSheet.SelectedIndex = 0;
            }
            catch (Exception var_3_B7)
            {
                result = null;
                return result;
            }
            result = excelDataReader;
            return result;
        }
        public static ExcelDataReader Read(string FileName)
        {
            ExcelDataReader excelDataReader = null;
            ExcelDataReader result;
            try
            {
                FileStream fileStream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                excelDataReader = new ExcelDataReader(fileStream);
                fileStream.Close();
            }
            catch (Exception var_2_1F)
            {
                result = null;
                return result;
            }
            result = excelDataReader;
            return result;
        }
        public ExcelDataReader Read()
        {
            ExcelDataReader excelDataReader = null;
            ExcelDataReader result;
            try
            {
                FileStream fileStream = new FileStream(this.m_FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                excelDataReader = new ExcelDataReader(fileStream);
                fileStream.Close();
            }
            catch (Exception var_2_24)
            {
                result = null;
                return result;
            }
            result = excelDataReader;
            return result;
        }
    }
}
